package com.runfast.common.service.impl;

import com.runfast.common.dao.IMapper;
import com.runfast.common.dao.mapper.RunfastCuserMapper;
import com.runfast.common.exception.BaseException;
import com.runfast.common.security.spring.UserDataDetails;
import com.runfast.common.service.BaseService;
import com.runfast.common.utils.SingleSendSms;
import com.runfast.common.web.entity.Result;
import com.runfast.common.web.entity.ResultCode;
import com.runfast.common.dao.model.RunfastCuser;
import com.runfast.common.dao.model.RunfastCuserExample;
import com.runfast.common.service.RunfastCuserService;
import com.runfast.common.web.shiro.ThirdLoginType;
import com.runfast.waimai.dao.model.RunfastSmsSendrecord;
import com.runfast.waimai.dao.model.RunfastSmsSendrecordExample;
import com.runfast.waimai.service.RunfastSmsSendrecordService;
import com.runfast.waimai.service.SmsService;
import net.bytebuddy.utility.RandomString;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.text.RandomStringGenerator;
import org.apache.commons.text.TextRandomProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class RunfastCuserServiceImpl extends BaseService<RunfastCuser, Integer, RunfastCuserExample> implements RunfastCuserService {

    @Autowired
    private RunfastSmsSendrecordService smsSendrecordService;

    @Autowired
    private SmsService smsService;


    @Override
    public RunfastCuserMapper getMapper() {
        return (RunfastCuserMapper)super.getMapper();
    }

    @Override
    public RunfastCuser getUserBy(String username, String password) {
        Validate.notBlank(username);
        Validate.notBlank(password);


        RunfastCuserExample runfastCuserExample = new RunfastCuserExample();
        runfastCuserExample.createCriteria().andMobileEqualTo(username);
        List<RunfastCuser> runfastCusers = this.selectByExample(runfastCuserExample);

        if (runfastCusers.size() == 0) throw new BaseException(ResultCode.ACCOUNT_NOT_EXIST);


        RunfastCuser runfastCuser = runfastCusers.get(0);

        if (!runfastCuser.getPassword().equalsIgnoreCase(password))
            throw new BaseException(ResultCode.ACCOUNT_USERNAME_OR_PASSWORD_ERROR);

        return runfastCuser;
    }


    @Override
    public UserDataDetails<RunfastCuser> checkMobielSmsCode(String mobile, String smsCode) {



        RunfastSmsSendrecordExample smsSendrecordExample = new RunfastSmsSendrecordExample();
        smsSendrecordExample.or().andSmstypeEqualTo(RunfastSmsSendrecord.SmsType.sms_login.getCode()).andPhoneEqualTo(mobile).andXcodeEqualTo(smsCode);
        smsSendrecordExample.setOrderByClause("id desc");
        List<RunfastSmsSendrecord> smsSendrecordList = smsSendrecordService.selectByExample(smsSendrecordExample);
        if(smsSendrecordList.isEmpty()) throw new BadCredentialsException("验证码错误");


        RunfastCuserExample runfastCuserExample = new RunfastCuserExample();
        runfastCuserExample.createCriteria().andMobileEqualTo(mobile);
        List<RunfastCuser> runfastCusers = this.selectByExample(runfastCuserExample);
        RunfastCuser cuser = null;
        if(runfastCusers.isEmpty()){
            cuser = new RunfastCuser();
            cuser.setMobile(mobile);
            cuser.setCreateTime(new Date());


            RandomStringGenerator.Builder builder = new RandomStringGenerator.Builder();
            String generate = builder.withinRange(48,57).build().generate(6);

            Result result = SingleSendSms.sendMsg(mobile, "{\"code\":\"" + generate + "\"}", "SMS_47920224");

            if(!result.isSuccess()){ //短信密码发送失败
                String errorMsg = result.getErrorMsg();
                switch (errorMsg){
                    case "13,mobile wrong":
                        errorMsg = "手机号码错误";
                        break;
                }


                throw new BadCredentialsException(errorMsg); //回滚事务
            }


            cuser.setPassword(DigestUtils.md5Hex(generate));

            this.insertSelective(cuser);

        }else{
            cuser = runfastCusers.get(0);
        }

        return new UserDataDetails<>(mobile, cuser.getPassword(), Collections.emptyList(),cuser);
    }

    @Override
    public UserDataDetails<RunfastCuser> checkThird(String thirdLoginId, String thirdLoginType) {
        ThirdLoginType loginType = ThirdLoginType.valueOf(thirdLoginType);

        RunfastCuserExample cuserExample = new RunfastCuserExample();

        switch (loginType){
            case QQ:
                cuserExample.createCriteria().andQqIdEqualTo(thirdLoginId);

                break;
            case WEIXIN:
                cuserExample.createCriteria().andWeixinIdEqualTo(thirdLoginId);
                break;
        }
        List<RunfastCuser> cusers = this.selectByExample(cuserExample);
        if(cusers.isEmpty()) throw new BadCredentialsException("第三方登陆失败");

        RunfastCuser cuser = cusers.get(0);


        return new UserDataDetails<>(cuser.getMobile(), cuser.getPassword(), Collections.emptyList(),cuser);
    }

    @Override
    public int updateAlias(String alias) {
        return getMapper().updateAlias(alias);
    }

    @Override
    public UserDataDetails<RunfastCuser> checkMobielPassword(String mobile, String password) {
        RunfastCuserExample cuserExample = new RunfastCuserExample();
        cuserExample.or().andMobileEqualTo(mobile).andPasswordEqualTo(password);
        List<RunfastCuser> cusers = this.selectByExample(cuserExample);
        if(cusers.isEmpty()) throw new UsernameNotFoundException("手机号不存在或者密码错误");
        RunfastCuser cuser = cusers.get(0);
        return new UserDataDetails<>(cuser.getMobile(), cuser.getPassword(), Collections.emptyList(), cuser);
    }
}